package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.constant.BsRelationConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.BsRelation;
import com.ruoyi.system.domain.dto.BsRelationNumDTO;
import com.ruoyi.system.domain.dto.UserBaseInfoDTO;
import com.ruoyi.system.domain.dto.YoukeCenterInfoDTO;
import com.ruoyi.system.domain.ro.BsRelationRO;
import com.ruoyi.system.domain.vo.BsRelationVO;
import com.ruoyi.system.mapper.BsRelationMapper;
import com.ruoyi.system.service.IBsRelationService;
import com.ruoyi.system.service.ISysUserService;
import io.github.classgraph.utils.Join;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 关系记录（关注、收藏、点赞）Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-25
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class BsRelationServiceImpl implements IBsRelationService {

    private final BsRelationMapper baseMapper;
    private final ISysUserService iSysUserService;

    /**
     * 说明 : 当前登录人是否关注
     */
    @Override
    public boolean checkIsAttention(Long aimId) {
        boolean b;
        if (aimId == null) {
            b = false;
        } else {
            BsRelationRO ro = BsRelationRO.builder()
                    .createById(SecurityUtils.getUserId())
                    .aimId(String.valueOf(aimId))
                    .type(BsRelationConstants.customer_attention)
                    .build();
            b = !queryList(ro).isEmpty();
        }
        log.info("是否关注此人:{}, 入参:{}", b, JSONObject.toJSONString(aimId));
        return b;
    }

    /**
     * 说明 : 统计 被关注数量/被点赞数量/被收藏数量
     */
    public Integer getTotalRelationByType(String type, String aimId) {
        Integer integer = baseMapper.selectCount(new QueryWrapper<BsRelation>().lambda()
                .eq(BsRelation::getType, type).eq(BsRelation::getAimId, aimId));
        return integer;
    }

    /**
     * 说明 : 统计 被关注数量/被点赞数量/被收藏数量
     */
    public Map<String, Integer> getTotalRelationByType(String type, Set<String> aimIds) {
        if (aimIds.isEmpty()) {
            return new HashMap<>();
        }
        String join = Join.join(",", aimIds);
        List<BsRelationNumDTO> totalRelationByType = baseMapper.getTotalRelationByType(join, type);
        Map<String, Integer> collect = totalRelationByType.stream().collect(Collectors.toMap(BsRelationNumDTO::getAimId, BsRelationNumDTO::getCountNum));
        aimIds.forEach(f -> {
            if (!collect.containsKey(f)) {
                collect.put(f, 0);
            }
        });
        return collect;
    }

    /**
     * 说明 : 统计 被关注数量/被点赞数量/被收藏数量
     */
    public Map<String, Boolean> getRelationByType(String type, Set<String> aimIds) {
        Long userId = SecurityUtils.getUserId();
        if (aimIds.isEmpty()) {
            return new HashMap<>();
        }
        String join = Join.join(",", aimIds);
        List<String> relationByType = baseMapper.getRelationByType(userId,join, type);
        HashMap<String, Boolean> result = new HashMap<>();
        aimIds.forEach(f->{
            result.put(f, false);
            if (ObjectUtil.isNotNull(relationByType) && relationByType.contains(f)) {
                result.put(f, true);
            }
        });
        return result;
    }

    /**
     * 查询关系记录（关注、收藏、点赞）
     */
    @Override
    public BsRelation queryById(Long id) {
        return baseMapper.selectById(id);
    }

    /**
     * 查询关系记录（关注、收藏、点赞）列表
     */
    @Override
    public List<BsRelation> queryPageList(BsRelationRO bo) {
        LambdaQueryWrapper<BsRelation> lqw = buildQueryWrapper(bo);
        return baseMapper.selectList(lqw);
    }

    /**
     * 查询关系记录（关注、收藏、点赞）列表
     */
    @Override
    public List<BsRelation> queryList(BsRelationRO bo) {
        LambdaQueryWrapper<BsRelation> lqw = buildQueryWrapper(bo);
        return baseMapper.selectList(lqw);
    }

    private LambdaQueryWrapper<BsRelation> buildQueryWrapper(BsRelationRO bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BsRelation> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getType()), BsRelation::getType, bo.getType());
        lqw.eq(bo.getCreateById() != null, BsRelation::getCreateById, bo.getCreateById());
        lqw.eq(StringUtils.isNotBlank(bo.getAimId()), BsRelation::getAimId, bo.getAimId());
        return lqw;
    }

    /**
     * 新增关系记录（关注、收藏、点赞）
     */
    @Override
    public Boolean insertByBo(BsRelationRO bo) {
        BsRelation add = BeanUtil.toBean(bo, BsRelation.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改关系记录（关注、收藏、点赞）
     */
    @Override
    public Boolean updateByBo(BsRelationRO bo) {
        BsRelation update = BeanUtil.toBean(bo, BsRelation.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 修改关系记录（关注、收藏、点赞）
     */
    @Override
    public Boolean deleteByParam(BsRelationRO ro) {
        baseMapper.delete(new UpdateWrapper<BsRelation>().lambda()
                .eq(BsRelation::getCreateById, ro.getCreateById())
                .eq(BsRelation::getAimId, ro.getAimId())
                .eq(BsRelation::getType, ro.getType())
        );
        return true;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BsRelation entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除关系记录（关注、收藏、点赞）
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 说明 : 关注/粉丝列表
     */
    @Override
    public List<BsRelationVO> queryPageListByScene(String scene) {
        List<BsRelationVO> selectResult = new ArrayList<>();
        Long userId = SecurityUtils.getUserId();
        switch (scene) {
            case "1":
                //关注
                selectResult = baseMapper.selectListByAttention(userId, BsRelationConstants.customer_attention);
                Set<Long> userIds = selectResult.stream().map(f -> Long.parseLong(f.getAimId())).collect(Collectors.toSet());
                Map<Long, UserBaseInfoDTO> userMap1 = iSysUserService.selectUserBaseInfo(userIds);
                selectResult.forEach(f -> {
                    f.setCreateUserInfo(userMap1.get(Long.parseLong(f.getAimId())));
                });
                break;
            case "2":
                //被关注
                selectResult = baseMapper.selectListByAttentioned(userId, BsRelationConstants.customer_attention);
                Set<Long> userId2 = selectResult.stream().map(BsRelationVO::getCreateById).collect(Collectors.toSet());
                Map<Long, UserBaseInfoDTO> userMap2 = iSysUserService.selectUserBaseInfo(userId2);
                selectResult.forEach(f -> {
                    f.setCreateUserInfo(userMap2.get(f.getCreateById()));
                });
                break;
            default:
                selectResult = new ArrayList<>();
        }
        return selectResult;
    }

    @Autowired
    private RedisCache redisCache;

    @Override
    public YoukeCenterInfoDTO youkeCenterCount() {
        Long userId = SecurityUtils.getUserId();
        String cache = Convert.toStr(redisCache.getCacheObject(getCacheKey(userId)));
        if (Validator.isNotEmpty(cache)) {
            log.info("缓存数据:{}", cache);
            return JSONObject.parseObject(cache, YoukeCenterInfoDTO.class);
        }
        YoukeCenterInfoDTO youkeCenterInfoDTO = baseMapper.youkeCenterCount(userId);
        if (Validator.isNotNull(youkeCenterInfoDTO)) {
            redisCache.setCacheObject(getCacheKey(userId), JSONObject.toJSONString(youkeCenterInfoDTO), 3, TimeUnit.MINUTES);
            return youkeCenterInfoDTO;
        }
        return YoukeCenterInfoDTO.builder().attentionNum(0).attentionedNum(0).strategyNum(0).commentNum(0).build();
    }

    private String getCacheKey(Long userId) {
        return Constants.PERSONAL_CENTER + userId;
    }
}
